/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.logging;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggerGroups;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;

import static org.springframework.boot.logging.LoggingSystem.ROOT_LOGGER_NAME;

/**
 * 设置日志级别服务类
 * 参考自：https://www.cnblogs.com/hollischuang/p/14200159.html 和 spring boot actuator
 * @author wangyandong
 * @date 2021/07/03 15:34
 *
 */
public class LoggerSettingService {
    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerSettingService.class);

    private  LoggingSystem loggingSystem;
    private  LoggerGroups loggerGroups;
    private  HashMap<String,String> defaultLoggerLevel;

    public LoggerSettingService(LoggingSystem loggingSystem, LoggerGroups loggerGroups) {
        Assert.notNull(loggingSystem, "LoggingSystem must not be null");
        Assert.notNull(loggerGroups, "LoggerGroups must not be null");

        this.loggingSystem = loggingSystem;
        this.loggerGroups = loggerGroups;
        this.defaultLoggerLevel = new HashMap<>();
        //记录一下默认的日志级别以进行后期还原
        Collection<LoggerConfiguration> configurations = this.loggingSystem.getLoggerConfigurations();
        if (configurations != null) {
            for (LoggerConfiguration configuration : configurations) {
                if(configuration.getConfiguredLevel()!=null) {
                    this.defaultLoggerLevel.put(configuration.getName(), configuration.getConfiguredLevel().name());
                }
            }
        }
    }

    public List<LoggerData> getLoggers() {
        List<LoggerData> loggers = new ArrayList<>();
        Collection<LoggerConfiguration> configurations = this.loggingSystem.getLoggerConfigurations();
        if (configurations != null) {
            LoggerData loggerData = null;
            for (LoggerConfiguration configuration : configurations) {
                loggerData = new LoggerData(configuration);
                loggers.add(loggerData);
            }
        }

//        if(this.loggerGroups!=null){
//            this.loggerGroups.forEach(group ->
//               loggers.put(new LoggerData(group.getConfiguredLevel())
//            );
//        }
        return loggers;
    }

    public LoggerData getLogger(String loggerName) {
        List<LoggerData> loggers = new ArrayList<>();
        LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(loggerName);
        if (configuration != null) {
            return new LoggerData(configuration);
        }

        return null;
    }

    /**
     * 设置根日志级别
     * @param level
     */
    public void setRootLoggerLevel(String level) {
        this.setLoggerLevel(ROOT_LOGGER_NAME,level);
    }

    /**
     * 设置日志级别
     * @param level
     */
    public void setLoggerLevel(String loggerName, String level) {
        LoggerConfiguration loggerConfiguration = loggingSystem.getLoggerConfiguration(loggerName);

        if (loggerConfiguration == null) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("no loggerConfiguration with loggerName " + level);
            }
            return;
        }

        if(level==null||"NULL".equalsIgnoreCase(level)){
            loggingSystem.setLogLevel(loggerName, null);
        }else{
            loggingSystem.setLogLevel(loggerName, LogLevel.valueOf(level));
        }
    }

    public HashMap<String,String> getDefaultLevels(){
        return this.defaultLoggerLevel;
    }

    /**
     * 支持的日志级别
     * @return
     */
    private List<String> supportLevels() {
        return loggingSystem.getSupportedLogLevels().stream().map(Enum::name).collect(Collectors.toList());
    }

    private NavigableSet<LogLevel> getLevels() {
        Set<LogLevel> levels = this.loggingSystem.getSupportedLogLevels();
        return (new TreeSet(levels)).descendingSet();
    }
}
